<template>
  <div class="fund-profile-page" :key="$route.fullPath">
    <!-- 顶部导航区：使用PageHeader组件增强导航体验 -->
    <el-page-header @back="$router.back()" content="基金详情" class="page-header">
      <template #prefix>
        <el-button icon="ArrowLeft" plain circle @click="$router.back()" />
      </template>
    </el-page-header>

    <!-- 基金标题区：增强信息层次感 -->
    <el-card class="title-card" shadow="hover" border-radius="12px">
      <div class="title-content">
        <div class="fund-name-wrap">
          <h1 class="fund-name">{{ profileData?.basicInfo?.name }}</h1>
          <el-tag :type="getFundTypeTagType(profileData?.basicInfo?.type)" size="large" class="fund-type-tag">
            {{ profileData?.basicInfo?.type }}
          </el-tag>
        </div>

        <!-- 使用Descriptions组件展示基础信息，更规整 -->
        <el-descriptions column="4" size="small" class="fund-base-info">
          <el-descriptions-item label="基金代码" label-class-name="desc-label">
            {{ profileData?.basicInfo?.code }}
          </el-descriptions-item>
          <el-descriptions-item label="基金公司" label-class-name="desc-label">
            {{ profileData?.basicInfo?.companyName }}
          </el-descriptions-item>
          <el-descriptions-item label="基金经理" label-class-name="desc-label">
            {{ profileData?.basicInfo?.managerName }}
          </el-descriptions-item>
          <el-descriptions-item label="最新净值" label-class-name="desc-label">
            <span class="latest-nav">
              {{ latestNetValue }}
            </span>
          </el-descriptions-item>
        </el-descriptions>
      </div>
    </el-card>

    <!-- 详情内容区：优化分栏布局 -->
    <el-row :gutter="24" class="detail-content">
      <!-- 左侧信息区 -->
      <el-col :span="16">
        <!-- 基金公告：使用折叠面板优化长文本展示 -->
        <el-card class="detail-card" shadow="hover" border-radius="12px">
          <template #header>
            <div class="card-header">
              <el-tag type="primary">最新公告</el-tag>
            </div>
          </template>
          <el-collapse v-model="activeAnnouncement">
            <el-collapse-item title="公告内容" name="1">
              <div class="announcement-content">
                <p v-if="profileData?.announcementContent">
                  {{ profileData?.announcementContent }}
                </p>
                <p v-else class="no-data">暂无公告信息</p>
              </div>
            </el-collapse-item>
          </el-collapse>
        </el-card>

        <!-- 业绩表现详情：使用Statistic组件增强数据展示 -->
        <el-card class="detail-card" shadow="hover" border-radius="12px">
          <template #header>
            <div class="card-header">
              <el-tag type="success">业绩表现详情</el-tag>
            </div>
          </template>
          <el-row :gutter="16" class="performance-row">
            <el-col :span="6">
              <el-statistic title="年化收益率"
                :value="formatFloat(profileData?.performance?.annualReturn, { addPercent: true })"
                :value-style="getReturnStyle(profileData?.performance?.annualReturn)" />
            </el-col>
            <el-col :span="6">
              <el-statistic title="夏普比率" :value="formatFloat(profileData?.performance?.sharpeRatio)"
                :value-style="{ color: '#409eff' }" />
            </el-col>
            <el-col :span="6">
              <el-statistic title="最大回撤"
                :value="formatFloat(profileData?.performance?.maxDrawdown, { addPercent: true })" suffix="%"
                :value-style="{ color: '#f56c6c' }" />
            </el-col>
            <el-col :span="6">
              <el-statistic title="波动率" :value="formatFloat(profileData?.performance?.stddev, { addPercent: true })"
                :value-style="{ color: '#e6a23c' }" />
            </el-col>
          </el-row>
        </el-card>

        <!-- 净值走势图表：添加时间范围选择器 -->
        <el-card class="detail-card" shadow="hover" border-radius="12px">
          <template #header>
            <div class="card-header">
              <el-tag type="info">净值走势</el-tag>
            </div>
          </template>
          <FundNetValueChart :netValueData="profileData?.netValueHistory" />
        </el-card>
      </el-col>

      <!-- 右侧信息区 -->
      <el-col :span="8">
        <!-- 标签区域：优化滚动体验 -->
        <el-card class="detail-card" shadow="hover" border-radius="12px">
          <template #header>
            <div class="card-header">
              <el-tag type="info">基金标签</el-tag>
            </div>
          </template>
          <div class="tags-container">
            <template v-if="fundTags.length > 0">
              <el-tag v-for="tag in fundTags" :key="tag" type="success" effect="light" class="fund-tag" size="small">
                {{ tag }}
              </el-tag>
            </template>
            <template v-else-if="!tagLoading">
              <span class="no-tags">暂无相关标签</span>
            </template>
            <template v-else>
              <!-- 标签加载中骨架屏（可选） -->
              <el-skeleton :rows="2" :width="['100px', '80px']" inline />
            </template>
          </div>
        </el-card>

        <SimilarFunds :fund-code="route.params.fundCode" />

        <!-- 持仓分析：增强数据可视化 -->
        <el-card class="detail-card" shadow="hover" border-radius="12px">
          <template #header>
            <div class="card-header">
              <el-tag type="warning">持仓分析</el-tag>
            </div>
          </template>
          <div v-if="Array.isArray(profileData?.holdings) && profileData.holdings.length > 0"
            class="holding-chart-container">
            <FundHoldingChart :holdings="profileData?.holdings" :size="{ width: '95%', height: '170px' }" />
          </div>
          <div v-else class="no-data">暂无持仓数据</div>

          <el-table v-if="Array.isArray(profileData?.holdings)" :data="profileData?.holdings" border size="small"
            class="holdings-table" highlight-current-row>
            <el-table-column prop="stockName" label="股票名称" align="left" />
            <el-table-column prop="holdingRatio" label="占比（%）" width="180">
              <template #default="scope">
                <div class="ratio-item">
                  <span>{{ (scope.row.holdingRatio * 100).toFixed(2) }}%</span>
                  <el-progress :percentage="scope.row.holdingRatio * 100" stroke-width="6" size="small" />
                </div>
              </template>
            </el-table-column>
          </el-table>
        </el-card>
      </el-col>
    </el-row>

    <!-- 加载状态：优化骨架屏结构 -->
    <el-skeleton v-if="loading" :loading="loading" class="loading-skeleton">
      <el-skeleton-item variant="text" style="width: 30%; margin-bottom: 20px" />
      <el-skeleton-item variant="rect" style="height: 120px; margin-bottom: 20px; border-radius: 12px" />

      <el-row :gutter="24" style="margin-bottom: 20px">
        <el-col :span="16">
          <el-skeleton-item variant="rect" style="height: 180px; border-radius: 12px" />
        </el-col>
        <el-col :span="8">
          <el-skeleton-item variant="rect" style="height: 180px; border-radius: 12px" />
        </el-col>
      </el-row>

      <el-row :gutter="24">
        <el-col :span="16">
          <el-skeleton-item variant="rect" style="height: 450px; border-radius: 12px" />
        </el-col>
        <el-col :span="8">
          <el-skeleton-item variant="rect" style="height: 260px; border-radius: 12px" />
        </el-col>
      </el-row>
    </el-skeleton>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import { useRoute } from 'vue-router'
import { ElMessage } from 'element-plus'

import { getFundProfile, getFundTagClusters } from '../../api/fundApi'
import FundNetValueChart from '@/components/funds/FundNetValueChart.vue'
import FundHoldingChart from '@/components/funds/FundHoldingChart.vue'
import SimilarFunds from '@/components/funds/SimilarFunds.vue'

// 路由参数
const route = useRoute()
const profileData = ref(null)
const loading = ref(true)
const activeAnnouncement = ref(['1']) // 控制公告折叠面板

// Data
const latestNetValue = ref(null)
const fundTags = ref([])
const tagLoading = ref(false);

// 加载基金画像数据
onMounted(async () => {
  try {
    const fundCode = route.params.fundCode;
    if (!fundCode) {
      ElMessage.warning('基金代码不存在');
      loading.value = false;
      return;
    }

    // 并行请求两个接口（提升加载速度，互不阻塞）
    const [profileRes, tags] = await Promise.all([
      // 请求基金详情（原有逻辑）
      getFundProfile(fundCode),
      // 请求基金标签（新增逻辑，单独处理错误避免影响主接口）
      (async () => {
        tagLoading.value = true;
        try {
          return await getFundTagsByCode(fundCode);
        } catch (tagErr) {
          ElMessage.warning('加载基金标签失败：' + (tagErr.message || '未知错误'));
          return []; // 标签加载失败返回空数组，不影响主页面
        } finally {
          tagLoading.value = false;
        }
      })()
    ]);

    // 处理基金详情数据（原有逻辑）
    profileData.value = profileRes.data;
    latestNetValue.value = getLatestNetValueItem(profileData.value?.netValueHistory)?.unitNav || '';

    // 处理标签数据（新增）
    fundTags.value = tags;

  } catch (err) {
    // 捕获基金详情接口的错误（主接口错误）
    ElMessage.error('加载画像失败：' + (err.response?.data?.message || err.message));
  } finally {
    // 所有请求完成后关闭全局加载
    loading.value = false;
  }
})

// 根据基金类型返回标签样式
const getFundTypeTagType = computed(() => (type) => {
  if (!type) return 'default'
  const typeMap = {
    '股票型': 'primary',
    '债券型': 'success',
    '混合型': 'warning',
    '货币型': 'info',
    '指数型': 'danger'
  }
  return typeMap[type] || 'default'
})

// 年化收益率样式（正负区分）
const getReturnStyle = (value) => {
  if (!value) return { color: '#666' }
  return value > 0 ? { color: '#27ae60' } : { color: '#e74c3c' }
}

/**
 * 从净值历史数组中获取最新日期对应的对象
 * @description 基于 ISO 格式日期字符串（YYYY-MM-DD）直接比较，无需转换 Date 对象，高效遍历一次数组（reduce 方案）
 * @param {Array<{ date: string; unitNav: number }>} netValueHistory - 净值历史数组，元素需包含 date（日期）和 unitNav（单位净值）字段
 * @returns {({ date: string; unitNav: number })|null} 最新日期对应的净值对象，若输入数组无效则返回 null
 * @example
 * // 示例数据（与你的业务数据格式一致）
 * const response = {
 *   netValueHistory: [
 *     { date: "2025-07-31", unitNav: 1.305 },
 *     { date: "2025-07-30", unitNav: 1.319 }
 *   ]
 * };
 * // 调用函数
 * const latestItem = getLatestNetValueItem(response.netValueHistory);
 * console.log(latestItem); // 输出：{ date: "2025-07-31", unitNav: 1.305 }
 */
function getLatestNetValueItem(netValueHistory) {
  // 1. 参数类型校验：必须传入数组
  if (!Array.isArray(netValueHistory)) {
    return null
  }

  // 2. 边界处理：数组为空时返回 null（避免后续逻辑报错）
  if (netValueHistory.length === 0) {
    console.warn('净值历史数组为空，无最新数据可返回');
    return null;
  }

  // 3. 核心逻辑：reduce 遍历一次数组，找到日期最新的对象
  // 原理：YYYY-MM-DD 格式的字符串可直接按字典序比较，等价于日期大小比较
  const latestItem = netValueHistory.reduce((prevItem, currentItem) => {
    // 比较当前元素与上一个元素的日期，保留日期更新的对象
    return currentItem.date > prevItem.date ? currentItem : prevItem;
  }, netValueHistory[0]); // 初始值设为数组第一个元素，确保遍历全覆盖

  return latestItem;
}

/**
 * 浮点数格式化（支持指定小数位、百分号模式，处理精度问题）
 * @param {number|string} num - 待格式化的小数（输入为有效小数，支持数字/字符串类型）
 * @param {Object} options - 配置项
 * @param {number} options.decimalPlaces - 保留的小数位数（默认2，需为非负整数）
 * @param {boolean} options.addPercent - 是否转为百分号形式（默认false）
 * @param {string} options.fallback - 无效值兜底显示（默认'0.00'，自动适配小数位）
 * @returns {string} 格式化后的结果字符串
 */
function formatFloat(num, {
  decimalPlaces = 2,
  addPercent = false,
  fallback = '0.00'
} = {}) {
  // 1. 基础校验：小数位数需为非负整数，否则默认2位
  const validDecimalPlaces = Math.max(0, Math.floor(Number(decimalPlaces) || 2));
  const power = Math.pow(10, validDecimalPlaces); // 放大倍数（如2位→100，3位→1000）

  // 2. 处理输入：转为数字，兼容字符串输入，处理异常值
  const parsedNum = Number(num);
  if (isNaN(parsedNum) || !isFinite(parsedNum)) {
    // 兜底值适配指定小数位（如兜底'0'且保留3位→'0.000'）
    const fallbackFixed = Number(fallback)
      .toFixed(validDecimalPlaces)
      .replace(/\.?0*$/, '') // 移除末尾多余0（可选，根据需求决定）
      .replace(/^\./, '0.'); // 处理'.5'→'0.5'
    return addPercent ? `${fallbackFixed}%` : fallbackFixed;
  }

  // 3. 核心逻辑：处理精度+四舍五入（根据是否百分号模式调整计算）
  let processedNum = parsedNum;
  if (addPercent) {
    // 百分号模式：先×100，再处理小数位（如0.1234→12.34%，保留2位）
    processedNum = parsedNum * 100;
  }

  // 放大→四舍五入（消除浮点数精度误差）→ 缩小
  const fixedNum = Math.round(processedNum * power) / power;

  // 4. 格式化：确保显示指定小数位（如3位→1.234，2位→1.23）
  const result = fixedNum.toFixed(validDecimalPlaces);

  // 5. 拼接百分号（如需）
  return addPercent ? `${result}%` : result;
}

/**
 * 根据基金代码获取对应的标签（核心函数：请求+解析）
 * @param {string} fundCode - 基金代码（如：511880.XSHG）
 * @returns {Promise<Array<string>>} 去重后的标签数组（失败返回空数组）
 */
const getFundTagsByCode = async (fundCode) => {
  try {
    // 1. 严格参数校验
    if (!fundCode || typeof fundCode !== 'string') {
      console.warn('getFundTagsByCode: 基金代码为空或格式错误');
      return [];
    }

    // 2. 请求聚类数据
    const response = await getFundTagClusters();
    const clusters = response.data || [];

    // 3. 响应格式容错（避免后端返回非数组）
    if (!Array.isArray(clusters)) {
      console.error('getFundTagsByCode: 接口返回格式异常，聚类数据需为数组');
      return [];
    }

    // 4. 解析标签并返回（调用内部工具函数）
    return parseTagsFromClusters(clusters, fundCode);
  } catch (error) {
    // 5. 全局错误捕获（网络异常、接口报错等）
    console.error('getFundTagsByCode: 获取基金标签失败', error.message);
    return []; // 失败返回空数组，防止页面崩溃
  }
};

/**
 * 内部工具函数：从聚类数组中匹配基金标签（纯逻辑无副作用）
 * @param {Array} clusters - 后端返回的聚类数组
 * @param {string} fundCode - 基金代码
 * @returns {Array<string>} 去重后的标签数组
 */
const parseTagsFromClusters = (clusters, fundCode) => {
  // 找到包含当前基金的目标聚类
  const targetCluster = clusters.find(cluster =>
    Array.isArray(cluster.funds) && cluster.funds.some(fund => fund.fundCode === fundCode)
  );

  // 提取关键词并去重（处理后端可能的重复标签）
  if (!targetCluster || !Array.isArray(targetCluster.keywords)) {
    return [];
  }

  const ret = [...new Set(targetCluster.keywords)];
  return ret
};
</script>

<style scoped>
.fund-profile-page {
  max-width: 1400px;
  margin: 0 auto;
  padding: 20px;
}

.page-header {
  margin-bottom: 20px;
}

.title-card {
  margin-bottom: 24px;
  border: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.title-content {
  padding: 20px;
}

.fund-name-wrap {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}

.fund-name {
  margin: 0;
  font-size: 20px;
  font-weight: 600;
}

.fund-type-tag {
  margin-top: 4px;
}

.fund-base-info {
  background: #f5f7fa;
  padding: 12px;
  border-radius: 6px;
}

.desc-label {
  color: #666;
  font-weight: 500;
}

.latest-nav {
  color: #27ae60;
  font-weight: 500;
}

.detail-content {
  margin-top: 10px;
}

.detail-card {
  margin-bottom: 24px;
  border: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  overflow: hidden;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 10px;
}

.tags-container {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  padding: 15px 5px;
  max-height: 180px;
  overflow-y: auto;
}

.tags-container::-webkit-scrollbar {
  width: 6px;
}

.tags-container::-webkit-scrollbar-thumb {
  background: #ddd;
  border-radius: 3px;
}

.performance-row {
  padding: 10px 0;
}

.el-statistic {
  text-align: center;
  padding: 15px 5px;
  background: #f9fafb;
  border-radius: 6px;
}

.el-statistic__title {
  color: #666;
  font-size: 14px;
  margin-bottom: 8px;
}

.el-statistic__content {
  font-size: 18px;
  font-weight: 500;
}

.time-range-selector {
  margin-right: 10px;
}

.holding-chart-container {
  margin: 15px auto;
}

.holdings-table {
  width: 100%;
  margin-top: 10px;
}

.ratio-item {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding-right: 5px;
}

.announcement-content {
  max-height: 300px;
  overflow-y: auto;
  padding: 10px;
  line-height: 1.6;
}

.announcement-content::-webkit-scrollbar {
  width: 6px;
}

.announcement-content::-webkit-scrollbar-thumb {
  background: #ddd;
  border-radius: 3px;
}

.no-data {
  color: #999;
  text-align: center;
  padding: 20px 0;
}

.loading-skeleton {
  padding: 20px 0;
}

/* 优化折叠面板样式 */
:deep(.el-collapse-item__content) {
  padding: 0 !important;
}

:deep(.el-collapse-item__header) {
  padding: 10px 0;
  font-weight: 500;
}
</style>